package cn.hamster3.mc.plugin.ball.velocity.listener;

import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
import cn.hamster3.mc.plugin.ball.common.entity.BallPlayerInfo;
import cn.hamster3.mc.plugin.ball.common.event.BallActions;
import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerLogoutEvent;
import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerPostConnectServerEvent;
import cn.hamster3.mc.plugin.ball.common.event.player.BallPlayerPreConnectServerEvent;
import cn.hamster3.mc.plugin.ball.velocity.util.BallVelocityUtils;
import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
import com.velocitypowered.api.event.player.ServerPreConnectEvent;
import com.velocitypowered.api.proxy.Player;

public class UpdatePlayerInfoListener {
    public static final UpdatePlayerInfoListener INSTANCE = new UpdatePlayerInfoListener();

    private UpdatePlayerInfoListener() {
    }

    @Subscribe(order = PostOrder.LATE)
    public void onServerConnect(ServerPreConnectEvent event) {
        if (event.getResult().isAllowed()) {
            return;
        }
        String name = event.getResult().getServer()
                .map(o -> o.getServerInfo().getName())
                .orElse(event.getOriginalServer().getServerInfo().getName());
        Player player = event.getPlayer();
        BallPlayerInfo playerInfo = BallVelocityUtils.getPlayerInfo(player, true);
        playerInfo.setGameServer(name);
        BallAPI.getInstance().sendRawBallMessage(
                BallAPI.BALL_CHANNEL,
                BallActions.BallPlayerPreConnectServer.name(),
                new BallPlayerPreConnectServerEvent(playerInfo, playerInfo.getGameServer(), name)
        );
        BallVelocityUtils.uploadPlayerInfo(playerInfo);
    }

    @SuppressWarnings("UnstableApiUsage")
    @Subscribe(order = PostOrder.LATE)
    public void onServerPostConnect(ServerPostConnectEvent event) {
        Player player = event.getPlayer();
        BallPlayerInfo playerInfo = BallVelocityUtils.getPlayerInfo(player, true);
        playerInfo.setGameServer(player.getCurrentServer().map(o -> o.getServerInfo().getName()).orElse(""));
        BallAPI.getInstance().sendRawBallMessage(
                BallAPI.BALL_CHANNEL,
                BallActions.BallPlayerPostConnectServer.name(),
                new BallPlayerPostConnectServerEvent(playerInfo)
        );
        BallVelocityUtils.uploadPlayerInfo(playerInfo);
    }

    @Subscribe(order = PostOrder.LATE)
    public void onDisconnect(DisconnectEvent event) {
        Player player = event.getPlayer();
        BallPlayerInfo playerInfo = BallVelocityUtils.getPlayerInfo(player, false);
        BallAPI.getInstance().sendRawBallMessage(
                BallAPI.BALL_CHANNEL,
                BallActions.BallPlayerLogout.name(),
                new BallPlayerLogoutEvent(playerInfo)
        );
        BallVelocityUtils.uploadPlayerInfo(playerInfo);
    }
}
